<template>
    <el-card class="topContainerCard">
        <div style="display: flex; justify-content: space-between">
            <span>表单名称：{{formName}}</span>
            <div>
                <div v-if="checkIsCanSave" style="display: inline-block;width: 240px; height: 30px; background-color: rgba(238,183,5,0.56);margin-right: 20px; text-align: center">
                    <span style="color: rgba(248,143,6,0.98); line-height: 30px">
                        历史版本只可查看，不可修改
                    </span>
                </div>
                <el-select v-model="currentVersion" placeholder="版本" style="width: 200px;margin-right: 10px" @change="selectChange()" v-loading.fullscreen.lock="fullscreenLoading">
                    <el-option
                        v-for="item in currentFlowVersionList"
                        :key="item.version"
                        :label="item.innerName"
                        :value="item.version"
                    />
                </el-select>
                <el-button @click="closeCurrentPage()">关闭</el-button>
                <el-button type="primary" :loading="saveFormJsonLoading" :disabled="checkIsCanSave" @click="saveFormJsonInfo()">保存</el-button>
            </div>
        </div>
    </el-card>

    <div class="allContainer">
        <div>
            <el-card :style="'width:' + leftWidth + 'px;' + 'height:' + height + 'px'">
                <div class="cardContainerDiv" :style="'height:' + (height - 40) + 'px'">
                    <el-divider>全局设置</el-divider>
                    <el-form :model="globalProperties" style="margin-bottom: 70px">
                        <el-form-item label="列布局" label-width="20%" prop="applicationName">
                            <el-radio-group v-model="globalProperties.colNum">
                                <el-radio :label="1">单列</el-radio>
                                <el-radio :label="2">双列</el-radio>
                                <el-radio :label="3">三列</el-radio>
                            </el-radio-group>
                        </el-form-item>
                    </el-form>

                    <el-divider>表单组件</el-divider>

                    <div>
                        <draggable
                            :list="formComponentList"
                            ghost-class="ghostClass"
                            chosen-class="chosenClass"
                            animation="300"
                            :force-fallback="true"
                            :sort="false"
                            :group="{name:'lowcode',pull:'clone',put:false}"
                            @start="onStart"
                            :clone="cloneDefaultField"
                            item-key="sourceId"
                            class="grid-container"
                        >
                            <template #item="{ element }">
                                <div class="drag-item">
                                    <div>
                                        <component :is="element.icon" style="font-size: 26px"/>
                                        <span>
                                            {{ element.name }}
                                        </span>
                                    </div>
                                </div>
                            </template>
                        </draggable>
                    </div>
                </div>
            </el-card>
        </div>

        <div>
            <el-card :style="'width:' + rightWidth + 'px;' + 'height:' + height + 'px'">
                <div class="cardContainerDiv" :style="'height:' + (height - 40) + 'px'">
                    <el-divider>预览</el-divider>
                    <el-form label-width="10%" :style="formCols">
                        <el-form-item v-for="(item, index) in formBuildList" :label="item.labelName">
                            <component :is="components[item.component]" :isEdit="false" :properties="item" :formBuildList="formBuildList"/>
                        </el-form-item>
                    </el-form>
                    <div class="formSubmitButton">
                        <el-button>取消</el-button>
                        <el-button type="primary">提交</el-button>
                    </div>
                    <el-divider style="margin-top: 60px">构建</el-divider>
                    <div class="draggableContainer">
                        <el-form>
                            <draggable :list="formBuildList"
                                       animation="300"
                                       :force-fallback="true"
                                       :group="{name:'lowcode'}"
                                       item-key="id"
                            >
                                <template #item="{ element }">
                                    <el-form-item class="itemClass" :label="element.labelName" label-width="10%">
                                        <component :is="components[element.component]" :isEdit="true" :properties="element" @click.stop="showComponentDrawer(element)"/>
                                        <component is="CloseCircleOutlined" class="closeClass" @click.stop="deleteComponent(element)"/>
                                    </el-form-item>
                                </template>
                            </draggable>
                        </el-form>

                    </div>
                </div>
            </el-card>
        </div>

        <div>
            <el-drawer
                v-model="isShowDrawer"
                :title="currentDrawerTitle"
                :lock-scroll="true"
                :close-on-click-modal="false"
            >
                <div>
                    <component :is="components[currentDrawer]" :properties="currentPropertiesCopy" ref="childFormRef" :formBuildList="formBuildList"/>
                </div>
                <template #footer>
                    <div style="flex: auto">
                        <el-button @click="cancelClick">取消</el-button>
                        <el-button type="primary" @click="confirmClick">确认</el-button>
                    </div>
                </template>
            </el-drawer>
        </div>
    </div>
</template>

<script name="BuildFlowForm" setup>
import draggable from "vuedraggable";
import {componentList} from "@/views/bpmn/form/formComponent.js";
import YwuFormInput from "@/views/bpmn/form/component/YwuFormInput.vue";
import YwuFormInputDrawer from "@/views/bpmn/form/drawer/YwuFormInputDrawer.vue";
import YwuFormSelectDrawer from "@/views/bpmn/form/drawer/YwuFormSelectDrawer.vue";
import YwuFormSelect from "@/views/bpmn/form/component/YwuFormSelect.vue";
import YwuFormCascaderSelectDrawer from "@/views/bpmn/form/drawer/YwuFormCascaderSelectDrawer.vue";
import YwuFormCascaderSelect from "@/views/bpmn/form/component/YwuFormCascaderSelect.vue";
import YwuFormCheckBoxDrawer from "@/views/bpmn/form/drawer/YwuFormCheckBoxDrawer.vue";
import YwuFormCheckBox from "@/views/bpmn/form/component/YwuFormCheckBox.vue";
import YwuFormDateDrawer from "@/views/bpmn/form/drawer/YwuFormDateDrawer.vue";
import YwuFormDate from "@/views/bpmn/form/component/YwuFormDate.vue";
import YwuFormInputNumberDrawer from "@/views/bpmn/form/drawer/YwuFormInputNumberDrawer.vue";
import YwuFormInputNumber from "@/views/bpmn/form/component/YwuFormInputNumber.vue";
import YwuFormRadioDrawer from "@/views/bpmn/form/drawer/YwuFormRadioDrawer.vue";
import YwuFormRadio from "@/views/bpmn/form/component/YwuFormRadio.vue";
import YwuFormRateDrawer from "@/views/bpmn/form/drawer/YwuFormRateDrawer.vue";
import YwuFormRate from "@/views/bpmn/form/component/YwuFormRate.vue";
import YwuFormSwitchDrawer from "@/views/bpmn/form/drawer/YwuFormSwitchDrawer.vue";
import YwuFormSwitch from "@/views/bpmn/form/component/YwuFormSwitch.vue";
import YwuFormTimeDrawer from "@/views/bpmn/form/drawer/YwuFormTimeDrawer.vue";
import YwuFormTime from "@/views/bpmn/form/component/YwuFormTime.vue";
import YwuFormTreeSelectDrawer from "@/views/bpmn/form/drawer/YwuFormTreeSelectDrawer.vue";
import YwuFormTreeSelect from "@/views/bpmn/form/component/YwuFormTreeSelect.vue";
import YwuFormUploadFileDrawer from "@/views/bpmn/form/drawer/YwuFormUploadFileDrawer.vue";
import YwuFormUploadFile from "@/views/bpmn/form/component/YwuFormUploadFile.vue";
import YwuFormUploadImageDrawer from "@/views/bpmn/form/drawer/YwuFormUploadImageDrawer.vue";
import YwuFormUploadImage from "@/views/bpmn/form/component/YwuFormUploadImage.vue";
import {
    queryFlowFormInfo, queryFlowVersionFormInfo,
    queryFlowVersionList, saveFlowFormJson
} from "@/request/flow";
import {ElNotification} from "element-plus";
import {computed, onMounted, ref, nextTick, onBeforeUnmount} from "vue";
import {useRoute, useRouter} from "vue-router";
import {deepCopy} from "@/utils/ywuCommon.js";

let route = useRoute();
let router = useRouter();

// 显式声明组件变量（确保被引用）
const components = { YwuFormInput, YwuFormInputDrawer, YwuFormSelect, YwuFormSelectDrawer,
    YwuFormCascaderSelect, YwuFormCascaderSelectDrawer, YwuFormCheckBox, YwuFormCheckBoxDrawer,
    YwuFormDate, YwuFormDateDrawer, YwuFormInputNumber,
    YwuFormInputNumberDrawer, YwuFormRadio, YwuFormRadioDrawer, YwuFormRate, YwuFormRateDrawer,
    YwuFormSwitchDrawer, YwuFormSwitch, YwuFormTime, YwuFormTimeDrawer, YwuFormTreeSelect, YwuFormTreeSelectDrawer,
    YwuFormUploadFileDrawer, YwuFormUploadFile, YwuFormUploadImageDrawer, YwuFormUploadImage};

let leftWidth = ref(0);
let rightWidth = ref(0);
let height = ref(0);
let globalProperties = ref({
    colNum: 1
});
let formComponentList = ref([]);
let formBuildList = ref([]);
let isShowDrawer = ref(false);
let currentDrawerTitle = ref("");
let currentDrawer = ref("");
let currentPropertiesCopy = ref({});
let currentElementId = ref("");
let saveFormJsonLoading = ref(false);
let currentFlowVersionList = ref([]);
let formName = ref("");
let currentVersion = ref(0);
let fullscreenLoading = ref(false);

let formCols = computed(() => {
    let res = "display: grid;gap: 16px;"
    let repeat = `grid-template-columns: repeat(${globalProperties.value.colNum}, 1fr);`
    return res + repeat;
})

let checkIsCanSave = computed(() => {
    if (currentFlowVersionList.value && currentFlowVersionList.value.length > 0) {
        // 如果当前表单存在草稿版本，那么只有草稿版本可以编辑，其他版本都不可以编辑
        if (currentFlowVersionList.value[0].version === 0) {
            return currentVersion.value !== 0;
        }
        // 如果当前表单不存在草稿版本，那么只有最新版本可以编辑，其他版本都不可以编辑
        return currentFlowVersionList.value[0].version !== currentVersion.value;
    } else {
        return true;
    }
})

onMounted(() => {
    nextTick(() => {
        calcWidthAndHeight();
    });
    // 在组件挂载时添加窗口大小改变的监听器
    window.addEventListener('resize', calcWidthAndHeight);
    // 配置可拖拽的组件列表
    formComponentList.value = componentList;
    // 查询当前表单的详情
    let currentQueryParams = route.query;
    fullscreenLoading.value = true
    // 查询版本列表
    queryFlowVersionList({id: currentQueryParams.id}).then(res => {
        if (res.code === '200') {
            currentFlowVersionList.value = res.data;
            if (currentFlowVersionList.value.length === 0) {
                // 没有历史版本，说明是草稿状态的表单，则查表单原始数据
                queryFlowFormInfo({id: currentQueryParams.id}).then(res => {
                    let formJson = res.data.formJson
                    // 序列化json
                    let jsonInfo = JSON.parse(formJson);
                    globalProperties.value = jsonInfo.globalProperties
                    formBuildList.value = jsonInfo.componentJson
                    formName.value = res.data.nameCn + " -- " + res.data.nameEn;
                    // 手动添加一个草稿版本的状态
                    currentFlowVersionList.value.push({
                        innerName: "草稿版本",
                        version: 0
                    })
                    currentVersion.value = 0;
                    fullscreenLoading.value = false
                }).catch(res => {
                    fullscreenLoading.value = false
                })
                return;
            }
            for (let index = 0; index < currentFlowVersionList.value.length; index++) {
                let tempInfo = currentFlowVersionList.value[index];
                if (tempInfo.version === 0) {
                    tempInfo.innerName = "草稿版本";
                } else {
                    tempInfo.innerName = "版本" + tempInfo.version;
                }
            }
            // 判断当前请求url中是否携带了version版本，如果携带了，则查询对应版本的数据，如果没带，则默认查询最新版本（有草稿则查草稿版本）
            if (currentQueryParams.version !== null && currentQueryParams.version !== undefined) {
                queryFlowVersionFormInfo({
                    resourceId: currentQueryParams.id,
                    version: currentQueryParams.version
                }).then(res => {
                    let formJson = res.data.formJson
                    // 序列化json
                    let jsonInfo = JSON.parse(formJson);
                    globalProperties.value = jsonInfo.globalProperties
                    formBuildList.value = jsonInfo.componentJson
                    formName.value = res.data.nameCn + " -- " + res.data.nameEn;
                    currentVersion.value = parseInt(currentQueryParams.version);
                })
            } else {
                queryFlowVersionFormInfo({
                    resourceId: currentQueryParams.id,
                    version: currentFlowVersionList.value[0].version
                }).then(res => {
                    let formJson = res.data.formJson
                    // 序列化json
                    let jsonInfo = JSON.parse(formJson);
                    globalProperties.value = jsonInfo.globalProperties
                    formBuildList.value = jsonInfo.componentJson
                    formName.value = res.data.nameCn + " -- " + res.data.nameEn;
                    currentVersion.value = currentFlowVersionList.value[0].version;
                })
            }
        }
        fullscreenLoading.value = false
    }).catch(res => {
        fullscreenLoading.value = false
    })
})

onBeforeUnmount(() => {
    // 在组件销毁前移除监听器，避免内存泄漏
    window.removeEventListener('resize', calcWidthAndHeight);
})

function calcWidthAndHeight() {
    let windowWidth = window.innerWidth;
    let windowHeight = window.innerHeight;
    if (windowHeight < 500) {
        height.value = 400;
    } else {
        height.value = windowHeight - 100;
    }
    if (windowWidth < 1000) {
        leftWidth.value = 200 - 15;
        rightWidth.value = 800;
    } else {
        leftWidth.value = windowWidth / 5 - 15;
        rightWidth.value = windowWidth - windowWidth / 5;
    }
}

function cloneDefaultField(e) {
    return deepCopy(e);
}

function onStart(e) {
    e.item._underlying_vm_.id = generateUUID();
}

function randomNumber() {
    return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
}

function generateUUID() {
    return (randomNumber() + randomNumber() + "-" + randomNumber() + "-" + randomNumber() +
        "-" + randomNumber() + "-" + randomNumber() + randomNumber() + randomNumber());
}

function showComponentDrawer(element) {
    currentElementId.value = element.id
    currentDrawerTitle.value = element.drawerTitle;
    currentDrawer.value = element.drawer;
    currentPropertiesCopy.value = {...element};
    isShowDrawer.value = true;
}

function cancelClick() {
    currentElementId.value = "";
    currentDrawerTitle.value = "";
    currentDrawer.value = "";
    currentPropertiesCopy.value = {};
    isShowDrawer.value = false;
}

let childFormRef = ref(null);
async function confirmClick() {
    // 调用子组件的校验方法（返回Promise）
    const isFormValid = await childFormRef.value.validateForm()
    if (isFormValid) {
        let index = -1;
        // 遍历当前列表，删除元素ID对应的数据
        for (let i = 0; i < formBuildList.value.length; i++) {
            if (formBuildList.value[i].id === currentElementId.value) {
                index = i;
            }
        }
        if (index >= 0) {
            formBuildList.value[index] = {...currentPropertiesCopy.value};
        }
        // 将备份的数据填充到原始数据对象中
        currentElementId.value = "";
        currentDrawerTitle.value = "";
        currentDrawer.value = "";
        currentPropertiesCopy.value = {};
        isShowDrawer.value = false;
    }
}

function deleteComponent(element) {
    let index = -1;
    // 遍历当前列表，删除元素ID对应的数据
    for (let i = 0; i < formBuildList.value.length; i++) {
        if (formBuildList.value[i].id === element.id) {
            index = i;
        }
    }
    if (index >= 0) {
        formBuildList.value.splice(index, 1);
    }
}

function closeCurrentPage() {
    window.close();
}

function saveFormJsonInfo() {
    saveFormJsonLoading.value = true;
    let currentQueryParams = route.query;
    // 构建json
    let jsonInfo = {
        globalProperties: globalProperties.value,
        componentJson: formBuildList.value
    }
    // 序列化字符串
    let jsonStr = JSON.stringify(jsonInfo)
    let param = {
        id: currentQueryParams.id,
        formJson: jsonStr
    }
    saveFlowFormJson(param).then(res => {
        if (res.code === "200") {
            saveFormJsonLoading.value = false;
            ElNotification({
                title: 'Success',
                message: res.message,
                type: 'success'
            })
            // 延迟一秒关闭页面
            setTimeout(() => {
                window.close();
            }, 1000);
        }
    })
}

function selectChange() {
    fullscreenLoading.value = true
    let currentQueryParams = route.query;
    router.replace({
        path: route.path,
        query: {
            id: currentQueryParams.id,
            version: currentVersion.value
        }
    })
    queryFlowVersionFormInfo({resourceId: currentQueryParams.id, version: currentVersion.value}).then(res => {
        let formJson = res.data.formJson
        // 序列化json
        let jsonInfo = JSON.parse(formJson);
        globalProperties.value = jsonInfo.globalProperties
        formBuildList.value = jsonInfo.componentJson
        formName.value = res.data.nameCn + " -- " + res.data.nameEn;
        fullscreenLoading.value = false
    }).catch(res => {
        fullscreenLoading.value = false
    })
}
</script>

<style scoped lang="less">
.grid-container {
    display: grid;
    grid-template-columns: repeat(3, 1fr); /* 每行3列 */
    gap: 12px; /* 项之间的间距 */
    padding: 8px 0;
}

.drag-item {
    font-size: 16px;
    color: #606266;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 60px;
    border: 1px solid #ddd;
    border-radius: 4px;
    padding: 8px;
    box-sizing: border-box;
    caret-color: transparent;
    background-color: #FAFCFF;
}

.drag-item > div {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px; /* 可选间距 */
}

.drag-item:hover {
    cursor: pointer;
    color: #409EFF;
    background-color: #EBEEF5;
}

.topContainerCard {
    height: 68px;
    margin-top: 6px;
    margin-bottom: 6px;
}

.allContainer {
    display: flex;
    justify-content: space-between;
    // 界面禁止选中
    -webkit-user-select: none; /* Safari */
    -moz-user-select: none; /* Firefox */
    -ms-user-select: none; /* IE10+ */
    user-select: none; /* Standard syntax */
}

.cardContainerDiv {
    overflow-y: auto;
}

.formSubmitButton {
    display: flex;
    align-items: center;
    justify-content: center;
}

/* 自定义整个滚动条 */
.cardContainerDiv::-webkit-scrollbar {
    width: 8px; /* 设置滚动条的宽度 */
}

/* 自定义滚动条轨道 */
.cardContainerDiv::-webkit-scrollbar-track {
    background: #f1f1f1; /* 设置轨道的背景颜色 */
}

/* 自定义滚动条的滑块（thumb） */
.cardContainerDiv::-webkit-scrollbar-thumb {
    background: #b7b7b7; /* 设置滑块的背景颜色 */
    border-radius: 20px;
}

/* 当滑块悬停或活动时的样式 */
.cardContainerDiv::-webkit-scrollbar-thumb:hover {
    background: #a9a9a9; /* 设置滑块在悬停状态下的背景颜色 */
}

.draggableContainer {
    width: 98%;
    //去除光标
    caret-color: transparent;
    .itemClass {
        position: relative;
        transition: box-shadow 0.3s ease;
        margin-bottom: 0.3%;
        .closeClass {
            display: none;
        }
    }
    .itemClass:hover {
        cursor: pointer;
        box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.5);
        .closeClass {
            position: absolute;
            color: #e76565;
            top: 2px;
            right: 2px;
            display: block;
        }
    }
}
.draggableContainer:hover {
    cursor: pointer;
}
</style>